from DeviceEvent import DeviceEvent
from enum import Enum,unique

class UnknownHandler(object):

    @staticmethod
    def handleDeviceEvent(event):
        return {
            DeviceEvent.FORCE_ALLOCATE_REQUEST: DeviceAllocationState.Allocated,
            DeviceEvent.CONNECTED_ONLINE : DeviceAllocationState.Checking_Availability,
            DeviceEvent.CONNECTED_OFFLINE : DeviceAllocationState.Unavailable,
            DeviceEvent.STATE_CHANGE_ONLINE : DeviceAllocationState.Checking_Availability,
            DeviceEvent.STATE_CHANGE_OFFLINE : DeviceAllocationState.Unavailable,
            DeviceEvent.FORCE_AVAILABLE : DeviceAllocationState.Available
        }.get(event, DeviceAllocationState.Unknown)

class CheckingAvailHandler(object):

    @staticmethod
    def handleDeviceEvent(event):
        return {
            DeviceEvent.FORCE_ALLOCATE_REQUEST : DeviceAllocationState.Allocated,
            DeviceEvent.AVAILABLE_CHECK_PASSED : DeviceAllocationState.Available,
            DeviceEvent.AVAILABLE_CHECK_FAILED : DeviceAllocationState.Unavailable,
            DeviceEvent.AVAILABLE_CHECK_IGNORED : DeviceAllocationState.Ignored,
            DeviceEvent.FORCE_AVAILABLE : DeviceAllocationState.Available,
            DeviceEvent.STATE_CHANGE_OFFLINE : DeviceAllocationState.Unavailable,
            DeviceEvent.DISCONNECTED : DeviceAllocationState.Unavailable,
        }.get(event, DeviceAllocationState.Checking_Availability)


class AvailableHandler(object):

    @staticmethod
    def handleDeviceEvent(event):
        return {
            DeviceEvent.ALLOCATE_REQUEST : DeviceAllocationState.Allocated,
            DeviceEvent.FORCE_ALLOCATE_REQUEST : DeviceAllocationState.Allocated,
            DeviceEvent.STATE_CHANGE_OFFLINE : DeviceAllocationState.Unavailable,
            DeviceEvent.DISCONNECTED : DeviceAllocationState.Unknown,
        }.get(event, DeviceAllocationState.Available)

class AllocatedHandler(object):

    @staticmethod
    def handleDeviceEvent(event):
        return {
            DeviceEvent.FREE_UNAVAILABLE : DeviceAllocationState.Unavailable,
            DeviceEvent.FREE_AVAILABLE : DeviceAllocationState.Available,
            DeviceEvent.FREE_UNRESPONSIVE : DeviceAllocationState.Available,
            DeviceEvent.FREE_UNKNOWN : DeviceAllocationState.Unknown,
        }.get(event, DeviceAllocationState.Allocated)

class UnavailableHandler(object):

    @staticmethod
    def handleDeviceEvent(event):
        return {
            DeviceEvent.FORCE_ALLOCATE_REQUEST : DeviceAllocationState.Allocated,
            DeviceEvent.DISCONNECTED : DeviceAllocationState.Unknown,
            DeviceEvent.FORCE_AVAILABLE : DeviceAllocationState.Available,
        }.get(event, DeviceAllocationState.Unavailable)


class IgnoredHandler(object):

    @staticmethod
    def handleDeviceEvent(event):
        return {
            DeviceEvent.DISCONNECTED : DeviceAllocationState.Unknown,
        }.get(event, DeviceAllocationState.Ignored)


@unique
class DeviceAllocationState(Enum):
    Unknown = UnknownHandler
    Ignored = IgnoredHandler
    Available = AvailableHandler
    Unavailable = UnavailableHandler
    Allocated = AllocatedHandler
    Checking_Availability = CheckingAvailHandler

print(DeviceAllocationState.Unknown.value.handleDeviceEvent(DeviceEvent.CONNECTED_ONLINE).value.handleDeviceEvent(DeviceEvent.AVAILABLE_CHECK_PASSED).value.handleDeviceEvent(DeviceEvent.DISCONNECTED))